import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:yp/enum/view_state.dart';
import 'package:yp/enum/view_state_error_type.dart';
import 'package:yp/exceptions/global_exception.dart';
import 'package:yp/util/util.dart';

class ViewStateError {
  ViewStateErrorType _errorType;
  String message;
  String errorMessage;

  ViewStateError(this._errorType, {this.message, this.errorMessage}) {
    _errorType ??= ViewStateErrorType.DEFAULT;
    message ??= errorMessage;
  }

  ViewStateErrorType get errorType => _errorType;

  /// 以下变量是为了代码书写方便,加入的get方法.严格意义上讲,并不严谨
  get isDefaultError => _errorType == ViewStateErrorType.DEFAULT;

  get isNetworkTimeOut => _errorType == ViewStateErrorType.NETWORK_TIMEOUT;

  get isUnauthorized => _errorType == ViewStateErrorType.UNAUTHORIZED;

  get isNoneNetwork => _errorType == ViewStateErrorType.NONE_NETWORK;

  get iServerError => _errorType == ViewStateErrorType.SERVER_ERROR;

  @override
  String toString() {
    return 'ViewStateError{errorType: $_errorType, message: $message, errorMessage: $errorMessage}';
  }
}

class GetxViewStateController extends GetxController {
  /// 当前的页面状态,默认为busy,可在viewModel的构造方法中指定;
  ViewState _viewState;

  /// 根据状态构造
  ///
  /// 子类可以在构造函数指定需要的页面状态
  /// FooModel():super(viewState:ViewState.Loading);
  GetxViewStateController({ViewState viewState})
      : _viewState = viewState ?? ViewState.SUCCESS {
    debugPrint('ViewStateModel---constructor--->$runtimeType');
  }

  /// ViewState
  ViewState get viewState => _viewState;

  set viewState(ViewState viewState) {
    _viewStateError = null;
    _viewState = viewState;
  }

  /// ViewStateError
  ViewStateError _viewStateError;

  ViewStateError get viewStateError => _viewStateError;

  /// 以下变量是为了代码书写方便,加入的get方法.严格意义上讲,并不严谨
  ///
  /// get
  bool get isLoading => viewState == ViewState.LOADING;

  bool get isSuccess => viewState == ViewState.SUCCESS;

  bool get isNone => viewState == ViewState.NONE;

  bool get isFailure => viewState == ViewState.FAILURE;

  /// set
  void setSuccess() {
    viewState = ViewState.SUCCESS;
  }

  void setLoading() {
    viewState = ViewState.LOADING;
  }

  void setNone() {
    viewState = ViewState.NONE;
  }

  /// [e]分类Error和Exception两种
  void setError(e, stackTrace, {String message}) {
    ViewStateErrorType errorType = ViewStateErrorType.DEFAULT;

    /// 见https://github.com/flutterchina/dio/blob/master/README-ZH.md#dioerrortype
    if (e is DioError) {
      if (e.type == DioErrorType.connectTimeout ||
          e.type == DioErrorType.sendTimeout ||
          e.type == DioErrorType.receiveTimeout) {
        // timeout
        errorType = ViewStateErrorType.NETWORK_TIMEOUT;
        message = e.error;
      } else if (e.type == DioErrorType.response) {
        // incorrect status, such as 404, 503...
        // message = e.error;
        message = "参数错误";
      } else if (e.type == DioErrorType.cancel) {
        message = e.error;
      } else {
        // dio将原error重新套了一层
        e = e.error;
        if (e is SocketException) {
          errorType = ViewStateErrorType.NETWORK_TIMEOUT;
          message = e.message;
        } else {
          message = e.message;
        }
      }
    }

    if (e is GlobalException) {
      if (e.type == ViewStateErrorType.NONE_NETWORK) {
        //  无网络
        errorType = ViewStateErrorType.NONE_NETWORK;
        message = e.error;
      } else if (e.type == ViewStateErrorType.SERVER_ERROR) {
        // 服务端异常
        errorType = ViewStateErrorType.SERVER_ERROR;
        message = e.error;
      } else if (e.type == ViewStateErrorType.UNAUTHORIZED) {
        errorType = ViewStateErrorType.UNAUTHORIZED;
        message = e.error;
      } else {
        errorType = ViewStateErrorType.DEFAULT;
        message = e.message;
      }
    }

    viewState = ViewState.FAILURE;

    _viewStateError = ViewStateError(
      errorType,
      message: message,
      errorMessage: e.toString(),
    );
    printErrorStack(e, stackTrace);
    showErrorMessage(message: message);
    onError(viewStateError);
  }

  void onError(ViewStateError viewStateError) {}

  /// 显示错误消息
  showErrorMessage({String message}) {
    if (viewStateError != null || message != null) {
      message ??= viewStateError.message;
      toast(message);
    }
  }

  @override
  String toString() {
    return 'BaseModel{_viewState: $viewState, _viewStateError: $_viewStateError}';
  }
}

/// [e]为错误类型 :可能为 Error , Exception ,String
/// [s]为堆栈信息
printErrorStack(e, s) {
  debugPrint('''
<-----↓↓↓↓↓↓↓↓↓↓-----error-----↓↓↓↓↓↓↓↓↓↓----->
$e
<-----↑↑↑↑↑↑↑↑↑↑-----error-----↑↑↑↑↑↑↑↑↑↑----->''');
  if (s != null) debugPrint('''
<-----↓↓↓↓↓↓↓↓↓↓-----trace-----↓↓↓↓↓↓↓↓↓↓----->
$s
<-----↑↑↑↑↑↑↑↑↑↑-----trace-----↑↑↑↑↑↑↑↑↑↑----->
    ''');
}
